home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <sysexits.h>
- #include "path.h"
-
- #ifndef lint
- static char RCSid[] = "$Header: uucp-queue.c,v 4.4 86/11/07 08:34:15 essick Exp $";
- #endif /* !lint */
-
- #ifndef MAILLOG
- #define MAILLOG "/usr/lib/mail/MailLog"
- #endif /* !MAILLOG */
-
- /*
- * uucp-queue
- *
- * This program takes a letter formatted for UUCP transmission
- * as standard input and a pair of arguements which correspond
- * to the host and user. The end result is an invocation of
- * UUX on some nearby machine with a properly expended path.
- *
- * Note that this method can result in loops. Let's hope that
- * things like sendmail will notice that the letter has been
- * through here before and do something about it....
- *
- * Ray Essick May 1, 1984
- *
- */
-
- int Debug = 0;
- int Pathalias = 0; /* paths have embedded %s */
- int PrefixBase = 0; /* expand user */
- char *Command = (char *) NULL; /* command to do */
- #define DFLTCOMMAND "/usr/bin/uux" /* normally this */
-
- extern char *strsave (); /* in misc.c */
- extern int strlower ();
- extern char *getpath (); /* in getpath.c */
- extern char *index ();
-
- main (argc, argv)
- int argc;
- char **argv;
- {
- int i,
- j,
- k;
- char *p,
- *q,
- *r;
- char *neighbor,
- *rest;
- char *remainder;
- char remotbuf[1024]; /* hold some bigass paths */
- char cmdline[1024];
- FILE * myson;
- FILE * popen ();
- char nextdoor[255]; /* my neighbor */
- char *host;
- char *domain; /* portion of full host */
- char *path;
- int fullroute; /* complete route ? */
- char *InvokedAs;
- char options[1024]; /* uux options */
-
- FILE * logfd; /* log traffic */
- char *Logfromuser = "UnSpecified";
- int messagebytes;
- char Logtouser[BUFSIZ];
-
- struct findpath_f hostpath;
- struct findpath_f *hostp;
- struct findpath_f *userp;
- struct findpath_f *findpath();
-
-
- InvokedAs = argv[0]; /* save command name */
- argc--;
- argv++;
- while (argc > 0 && argv[0][0] == '-') /* parse options */
- { /* wish i had getopt() */
- if (strcmp (argv[0], "-") == 0) /* end of options */
- {
- argc--;
- argv++;
- break;
- }
- if (strcmp (argv[0], "-c") == 0) /* -c == common */
- {
- PrefixBase++;
- argc--;
- argv++;
- continue;
- }
- if (strcmp (argv[0], "-d") == 0) /* -d == Debugging */
- {
- Debug++;
- argc--;
- argv++;
- continue;
- }
- if (strcmp (argv[0], "-p") == 0) /* -p == pathalias format */
- {
- Pathalias++;
- argc--;
- argv++;
- continue;
- }
- if (strncmp (argv[0], "-f", 2) == 0) /* -fsender */
- {
- if (argv[0][2] != '\0') /* not bare option */
- {
- Logfromuser = strsave (&argv[0][2]);
- }
- argc--;
- argv++;
- continue;
- }
- if (strncmp (argv[0], "-C", 2) == 0) /* -Ccommand */
- {
- p = &argv[0][2]; /* "command" */
- if (*p == 0)
- {
- goto usage; /* empty command */
- }
- if (Command != (char *) NULL)
- {
- fprintf (stderr, "Only one -C option allowed\n");
- goto usage;
- }
- Command = p; /* save the comand */
- argc--;
- argv++;
- }
- fprintf (stderr, "Unknown option: %s\n", argv[0]);
- goto usage;
- }
- /*
- * if "Command" is still null, load the default
- */
- if (Command == (char *) NULL)
- {
- Command = DFLTCOMMAND;
- }
-
- /*
- * collect any options that we should pass to uux
- */
- options[0] = '\0'; /* empty option list */
- while (argc > 0 && **argv == '-') /* while its a - */
- {
- strcat (options, " ");
- strcat (options, argv[0]);
- argv++;
- argc--;
- }
- if (Debug)
- fprintf (stderr, "option line is: %s\n", options);
- /*
- * time for the nitty gritty
- */
- if (argc < 2)
- {
- fprintf (stderr,
- "Improper argument count\n");
- usage:
- fprintf (stderr,
- "Usage: %s [-p] [-c] [-Ccommand] [-d] [-] [commandoptions] host user\n",
- InvokedAs);
- exit (EX_USAGE);
- }
-
- host = *argv;
- argc--;
- argv++; /* count it out */
- if (Debug)
- fprintf (stderr, "Looking for Host: %s\n", host);
-
- domain = strsave (host); /* make a copy */
- strlower (domain); /* and go lower case */
- hostp = findpath (domain); /* get a route */
- if (hostp != (struct findpath_f *) NULL) /* is a path */
- {
- hostpath = *hostp;
- }
- else
- {
- hostpath.fp_path = (char *) NULL;
- hostpath.fp_matched = (char *) NULL;
- hostpath.fp_fullroute = 1;
- }
-
- if (hostpath.fp_path != (char *) NULL) /* got a path? */
- {
- if (Pathalias &&
- strlen (hostpath.fp_path) >= 2 &&
- strncmp (hostpath.fp_path, "%s", 2) == 0)
- {
- /*
- * we got a path like "%s" or "%s@site"
- * but we really want a path of the form
- * "host!...%s...." so we can strip a
- * leading host...
- */
- fprintf (stderr, "%s: %s: no leftmost host!.\n",
- InvokedAs, hostpath.fp_path);
- exit (EX_UNAVAILABLE);
- }
- neighbor = nextdoor;
- q = hostpath.fp_path;
- while (*q && *q != '!') /* get first hop */
- *neighbor++ = *q++;
- *neighbor = '\0'; /* terminate */
-
- remainder = strsave (++q); /* rest of path */
- *--q = '!'; /* and restore */
- if (!Pathalias) /* append a %s */
- {
- char buf[1024];
- sprintf (buf, "%s%%s", remainder);
- free (remainder);
- remainder = strsave (buf);
- }
- }
- else
- {
- /*
- * no path to the site or any of the enclosing domains.
- * set things up as if we had a straight shot to the site.
- */
- strcpy (nextdoor, host);
- remainder = "%s"; /* printf fmt */
- }
-
- #ifdef ALIASESINPATH
- /*
- * if our first hop is through ALIASEINPATH, we shouldn't
- * be doing this; we should have defered this letter somewhere
- * upstream.
- * so, to keep from going to non-existent sites, we will
- * defer this letter.
- */
- if (strcmp (nextdoor, ALIASESINPATH) == 0)
- {
- if (Debug)
- {
- fprintf (stderr, "first hop through %s, defer the letter\n",
- ALIASESINPATH);
- }
- exit (EX_TEMPFAIL);
- }
- #endif /* ALIASESINPATH */
-
- sprintf (cmdline, "%s %s %s!rmail",
- Command, options, nextdoor);
-
- /*
- * now for each user...
- */
-
- Logtouser[0] = '\0'; /* empty the string */
- while (argc > 0)
- {
- char addon[1024];
- char userbuf[512];
- char buildbuf[1024];
- char *touser;
- char *up; /* hold user */
- char *hp; /* hold host */
-
- if (Debug)
- fprintf (stderr, "User: %s\n", *argv);
- if (!PrefixBase)
- {
- /*
- * see if we have a "full route". if so, we want to hand
- * off just the plain "user" field. if not, we need to
- * build a "host!user" string and hand that to the
- * segment that builds the rmail arguements.
- */
- if (hostpath.fp_fullroute)
- {
- /*
- * know the whole thing
- */
- touser = *argv;
- }
- else
- {
- /*
- * incomplete route; prepend the host name
- */
- sprintf (buildbuf, "%s!%s", host, *argv);
- touser = buildbuf;
- }
- }
- else
- {
- /*
- * PrefixBase work
- *
- * find a path to the user.
- * compare it for common prefixes with that to host
- * remove first hop
- * rebuild new user information.
- * pass it on down to the command line formatting.
- *
- * have to make some sort of distinction between how an
- * address like site!user will come across vs how
- * an address like hop!site!user will come across.
- * we don't want to do the user path expansion for the
- * second case. i'm not sure how i want to do this.
- */
- }
-
- sprintf (userbuf, remainder, touser); /* make arg */
- sprintf (addon, " \"(%s)\"", userbuf);
- if (Debug)
- {
- fprintf (stderr, "\ttouser = %s\n", touser);
- fprintf (stderr, "\tadded to cmdline: %s\n", addon);
- }
- strcat (cmdline, addon); /* append to cmd */
- #ifdef MAILLOG
- strcat (Logtouser, " "); /* separator */
- strcat (Logtouser, *argv); /* and user */
- #endif /* MAILLOG */
- argc--;
- argv++;
- }
- if (Debug)
- {
- printf ("Doing: %s\n", cmdline);
- exit (EX_UNAVAILABLE);
- }
- myson = popen (cmdline, "w"); /* send text here */
- if (myson == NULL)
- {
- printf ("Couldn't make pipe to \"%s\"\n", cmdline);
- exit (EX_UNAVAILABLE);
- }
-
- messagebytes = 0;
- while ((i = getc (stdin)) != EOF)
- {
- putc (i, myson); /* copy it all */
- messagebytes++;
- }
-
-
- #ifdef MAILLOG
- /*
- * LOG the following:
- *
- * Neighbor, Fromstring, Size, FullPath, [users]
- */
- if ((logfd = fopen (MAILLOG, "a")) != (FILE *) NULL)/* if there */
- {
- fprintf (logfd, "%s\t%s\t%d\t%s\t%s\n",
- nextdoor, Logfromuser, messagebytes,
- hostpath.fp_path, Logtouser);
- /*
- * could include [%s ] and Logtouser
- */
- fclose (logfd);
- }
- #endif /* MAILLOG */
-
-
- exit (pclose (myson) >> 8);
-
- }
-